package com.ehotting.mqbd.core.helper;


import com.alibaba.fastjson.JSON;
import com.ehotting.eaf.core.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.net.*;
import java.util.List;


@Component
@ConfigurationProperties(prefix = "config")
public class IPHelper {

    private static final Logger logger = LoggerFactory.getLogger(IPHelper.class);

    public List<String> ipPreList;

    public String getIp() {
        // 判断是否在Docker环境中
        String osName = System.getProperty("os.name").toLowerCase();
        boolean isDocker = osName.contains("docker");
        String physicalIp = null;
        logger.info("isDocker: {}" , isDocker);
        if (isDocker) {
            // 在Docker环境中获取物理机IP地址（可以使用Docker宿主机的网络接口名称或环境变量）
            physicalIp = getPhysicalIpInDocker();
        } else {
            // 在物理环境中获取物理机IP地址（根据操作系统类型选择相应的方法）
            String os = System.getProperty("os.name").toLowerCase();
            if (os.contains("win")) {
                physicalIp = getPhysicalIpWindows();
                logger.info("Physical IP: " + physicalIp);
            } else if (os.contains("nix") || os.contains("nux") || os.contains("mac")) {
                physicalIp = getPhysicalIpLinux();
                logger.info("Physical IP: {}" , physicalIp);
            } else {
                logger.error("Unsupported operating system.");
            }
        }
        return physicalIp;
    }

    /* 对于Linux操作系统，可以使用Java的`NetworkInterface`类来获取物理机IP地址。示例代码如下：*/
    private String getPhysicalIpLinux() {
        try {
            // 获取默认网络接口
            NetworkInterface networkInterface = NetworkInterface.getNetworkInterfaces().nextElement();
            if (networkInterface != null) {
                logger.debug("networkInterface.getInterfaceAddresses().size():{}",networkInterface.getInterfaceAddresses().size());
                for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
                    String ip = getHostAddress(interfaceAddress.getAddress());
                    if( ip!=null ){
                        return ip;
                    }
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }
        return null;
    }

    /* 对于Windows操作系统，可以使用Java的`InetAddress`类来获取物理机IP地址。示例代码如下：*/
    private String getPhysicalIpWindows() {
        try {
            // 获取本地主机地址
            InetAddress localHost = InetAddress.getLocalHost();
            // 获取主机名称
            String hostName = localHost.getHostName();
            // 获取所有IP地址
            InetAddress[] addresses = InetAddress.getAllByName(hostName);
            for (InetAddress address : addresses) {
                String ip = getHostAddress( address);
                if(ip!=null){
                    return ip;
                }
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 使用Docker宿主机的网络接口名称获取物理机IP地址
     * @return
     */
    private String getPhysicalIpInDocker() {
        String interfaceName = "eth0"; // 替换为你的宿主机网络接口名称
        try {
            NetworkInterface networkInterface = NetworkInterface.getByName(interfaceName);
            if (networkInterface != null) {
                for (InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) {
                    String ip = getHostAddress(interfaceAddress.getAddress());
                    if(ip!=null){
                        return ip;
                    }
                }
            } else {
                logger.info("Network interface not found: " + interfaceName);
            }
        } catch (SocketException e) {
            e.printStackTrace();
        }

        // 使用Docker宿主机的环境变量获取物理机IP地址
        String physicalIp = System.getenv("HOST_IP"); // 或者使用 DOCKER_HOST_IP
        logger.info("HOST_IP: {}" , physicalIp);
        if (physicalIp != null) {
            return physicalIp;
        } else {
            logger.info("Physical IP not found in environment variables.");
        }
        return null;
    }

    private String getHostAddress(InetAddress address){
        logger.debug("!address.isLoopbackAddress():{}",!address.isLoopbackAddress());
        logger.debug("address instanceof Inet4Address :{}",address instanceof Inet4Address );
        if (!address.isLoopbackAddress() && address instanceof Inet4Address ) {
            String ip = address.getHostAddress();
            logger.debug("address.getHostAddress(): {}" , ip);
            if(isStartsWith(ip)){
                return ip;
            }
        }
        return null;
    }



    private boolean isStartsWith(String ip){
        if(ipPreList==null || ipPreList.size()==0) {
            return true;
        }
        if(StringUtils.isEmpty(ip)){
            return false;
        }

        for(String s : ipPreList){
            if(ip.startsWith(s)) {
                return true;
            }
        }
        logger.info("StartsWith-ip:{},ipPreList:{},result:false.",ip,JSON.toJSONString(ipPreList));
        return false;
    }

    public List<String> getIpPreList() {
        return ipPreList;
    }

    public void setIpPreList(List<String> ipPreList) {
        this.ipPreList = ipPreList;
    }

    public static void main(String[] args) {
        String ip = "192.168.1.1";
        System.out.println(ip.startsWith("192.168."));
    }
}